package com.bot.snakeRunningSystem.pool;

import com.bot.snakeRunningSystem.utils.SnakeInterface;
import org.joor.Reflect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.UUID;

@Component
public class Consumer extends Thread{

    private Snake snake;
    private static RestTemplate restTemplate;

    private final static String reveiveSnakeMoveUrl = "http://127.0.0.1:3000/pk/receive/snake/move/";

    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        Consumer.restTemplate = restTemplate;
    }

    public void startTimeout(Integer timeout, Snake snake) {
        this.snake = snake;
        this.start();

        // 执行完run函数里面的内容之后执行该函数之后的代码
        // 或者执行run函数达到超过timeout时间之后，执行该函数之后的代码
        try {
            this.join(timeout);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 执行时间过长，中断该进程
            this.interrupt();
        }
    }

    private String addUid(String code, String uid) { // 在code中的Snake类名后添加uid
        int k = code.indexOf(" implements com.bot.snakeRunningSystem.utils.SnakeInterface");
        return code.substring(0, k) + uid + code.substring(k);

    }

    @Override
    public void run() {
        UUID  uuid = UUID.randomUUID();
        String uid = uuid.toString().substring(0, 8);
        SnakeInterface snakeInterface = Reflect.compile( // 动态编译一段代码, 类重名只会编译一次, 因为多个用户每次代码不一定一样，所以需要区分
                "com.bot.snakeRunningSystem.utils.Snake" + uid,
                addUid(snake.getSnakeCode(), uid)
        ).create().get();

        Integer nextMove = snakeInterface.nextMove(snake.getInput());
        System.err.println("move: " + snake.getUserId() + " " + nextMove);
        MultiValueMap<String, String> data = new LinkedMultiValueMap<>();
        data.add("user_id", snake.getUserId().toString());
        data.add("direction", nextMove.toString());
        restTemplate.postForObject(reveiveSnakeMoveUrl, data, String.class);
    }
}
